/*
 * Task.java
 *
 * Created on Jul 25, 2013, 3:29:14 PM
 */
package swingExtended.todoQueue;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.swing.ImageIcon;
import org.jdesktop.swingx.util.GraphicsUtilities;
import processor.images.ImageProcessor;
import stringFunctions.StringFunctions;
import swingExtended.EstimatingProgressBar;

/**
 *
 * @author g1wshimu
 */
public class Task<T> extends javax.swing.JPanel {

    private final static String IMAGE_DIR = "data/images/";
    
    /**
     * Encapsulates the Icons used by the Buttons.
     */
    private static enum ButtonIcons {
        
        CANCEL(IMAGE_DIR + "cancel.png", 20, 20),
        UP(IMAGE_DIR + "up_carrot.png", 15, 10),
        DOWN(IMAGE_DIR + "down_carrot.png", 15, 10);
        
        private final ImageIcon ICON;

        private ButtonIcons(String url, int width, int height) {
            BufferedImage img;
            try {
                img = ImageProcessor.loadImage(new File(url));
                img = GraphicsUtilities.createThumbnail(img,
                        width, height);
            } catch (IOException ex) {
                img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
            }
            this.ICON = new ImageIcon(img);
        }
    }
    
    private final TaskManager STACK;
    private int index;
    private final T DATA;
    private boolean enableRemove = true, enableUp = true, enableDown = true;

    /** Creates new form Task */
    protected Task(TaskManager stack, T data) {
        initComponents();
        Dimension dim = new Dimension();
        dim.setSize(this.getMaximumSize().getWidth(), this.getPreferredSize().getHeight());
        this.setMaximumSize(dim);
        buttonRemove.setIcon(ButtonIcons.CANCEL.ICON);
        buttonUp.setIcon(ButtonIcons.UP.ICON);
        buttonDown.setIcon(ButtonIcons.DOWN.ICON);

        this.STACK = stack;
        this.DATA = data;
        this.label.setText(StringFunctions.truncate(data.toString(), 25));
    }

    public T getData() {
        return DATA;
    }

    /**
     * Disables the buttomUp and buttonDown buttons accordingly
     */
    protected void positionChanged() {
        boolean upEnabled = (index != 0);
        // First item, cannot move up in the queue
        buttonUp.setEnabled(upEnabled);
        buttonUp.setVisible(upEnabled);

        boolean downEnabled = (index != STACK.getItemCount() - 1);
        // Last item, cannot move down in the queue
        buttonDown.setEnabled(downEnabled);
        buttonDown.setVisible(downEnabled);

        //buttonUp.validate();
        //buttonDown.validate();
    }

    protected void setIndex(int index) {
        this.index = index;
    }

    public void refresh() {
        this.buttonUp.repaint();
        this.buttonDown.repaint();
    }

    public EstimatingProgressBar getProgressBar() {
        return this.progressBar;
    }
    
    public void enableRemove(boolean remove) {
        this.enableRemove = remove;
        this.buttonRemove.setEnabled(remove);
    }

    public boolean isRemovable() {
        return this.enableRemove;
    }

    public void enableUp(boolean up) {
        this.enableUp = up;
        this.buttonUp.setEnabled(up);
    }

    public boolean canMoveUp() {
        return this.enableUp;
    }

    public void enableDown(boolean down) {
        this.enableDown = down;
        this.buttonDown.setEnabled(down);
    }

    public boolean canMoveDown() {
        return this.enableDown;
    }

    public void remove() {
        if (enableRemove) {
            STACK.removeItem(index);
            repaintButtons();
        }
    }

    public void moveUp() {
        if (enableUp) {
            STACK.swapItem(index, index - 1);
            repaintButtons();
        }
    }

    public void moveDown() {
        if (enableDown) {
            STACK.swapItem(index, index + 1);
            repaintButtons();
        }
    }

    private void repaintButtons() {
        this.buttonUp.repaint();
        this.buttonDown.repaint();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        label = new javax.swing.JLabel();
        buttonDown = new javax.swing.JToggleButton();
        buttonUp = new javax.swing.JToggleButton();
        buttonRemove = new javax.swing.JToggleButton();
        progressBar = new swingExtended.EstimatingProgressBar();

        setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
        });

        label.setText("jLabel1");

        buttonDown.setFont(new java.awt.Font("Dialog", 0, 10));
        buttonDown.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDownActionPerformed(evt);
            }
        });

        buttonUp.setFont(new java.awt.Font("Dialog", 0, 10));
        buttonUp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonUpActionPerformed(evt);
            }
        });

        buttonRemove.setFont(new java.awt.Font("Dialog", 0, 10));
        buttonRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonRemoveActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(label)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 137, Short.MAX_VALUE)
                        .addComponent(buttonRemove, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(buttonUp)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonDown))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(label))
                    .addComponent(buttonRemove, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(buttonDown, javax.swing.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE)
                    .addComponent(buttonUp, javax.swing.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE)))
        );
    }// </editor-fold>//GEN-END:initComponents

private void buttonDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDownActionPerformed
    moveDown();
}//GEN-LAST:event_buttonDownActionPerformed

private void buttonUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonUpActionPerformed
    moveUp();
}//GEN-LAST:event_buttonUpActionPerformed

private void buttonRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRemoveActionPerformed
    remove();
}//GEN-LAST:event_buttonRemoveActionPerformed

private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
    System.out.println(this.label.getText());
}//GEN-LAST:event_formMouseClicked
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToggleButton buttonDown;
    private javax.swing.JToggleButton buttonRemove;
    private javax.swing.JToggleButton buttonUp;
    private javax.swing.JLabel label;
    private swingExtended.EstimatingProgressBar progressBar;
    // End of variables declaration//GEN-END:variables
}
